/*
 * Copyright 2013-2019 Xia Jun(3979434@qq.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************************************
 *                                                                                     *
 *                        Website : http://www.farsunset.com                           *
 *                                                                                     *
 ***************************************************************************************
 */
package com.master.demo.im.component.handler;

import com.alibaba.fastjson.JSON;
import com.farsunset.cim.constant.ChannelAttr;
import com.farsunset.cim.group.SessionGroup;
import com.farsunset.cim.group.TagSessionGroup;
import com.farsunset.cim.handler.CIMRequestHandler;
import com.farsunset.cim.model.ReplyBody;
import com.farsunset.cim.model.SentBody;
import com.master.common.validator.ValidatorUtil;
import com.master.demo.im.component.handler.annotation.CIMHandler;
import com.master.demo.im.component.redis.SignalRedisTemplate;
import com.master.demo.im.pojo.command.SessionCommand;
import com.master.demo.im.service.ISessionService;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import org.springframework.http.HttpStatus;

import javax.annotation.Resource;

/**
 * 客户长连接 账户绑定实现
 *
 * @author: Yang
 * @date: 2022/07/05
 * @version: 1.0.0
 * Copyright Ⓒ 2022 Master Computer Corporation Limited All rights reserved.
 */
@CIMHandler(key = "client_bind")
public class BindHandler implements CIMRequestHandler {
    @Resource
    private SessionGroup sessionGroup;
    @Resource
    private TagSessionGroup tagsessionGroup;
    @Resource
    private ISessionService sessionService;
    @Resource
    private SignalRedisTemplate signalRedisTemplate;

    @Override
    public void process(Channel channel, SentBody body) {
        ReplyBody reply = new ReplyBody();
        reply.setKey(body.getKey());
        reply.setCode(HttpStatus.OK.value());
        reply.setTimestamp(System.currentTimeMillis());

        String uid = body.get("uid");
        if (ValidatorUtil.isNull(body.get("roomId"))) {
            bindSession(channel, body, reply, uid);
        } else {
            bindMember(channel, body, reply, uid);
        }
    }

    /**
     * 单聊上线
     *
     * @param channel
     * @param body
     * @param reply
     * @param uid
     */
    private void bindSession(Channel channel, SentBody body, ReplyBody reply, String uid) {
        SessionCommand command = SessionCommand.builder()
                .uid(uid).nid(channel.attr(ChannelAttr.ID).get()).deviceId(body.get("deviceId"))
                .channel(body.get("channel")).deviceName(body.get("deviceName")).appVersion(body.get("appVersion")).osVersion(body.get("osVersion"))
                .language(body.get("language")).build();
        channel.attr(ChannelAttr.UID).set(uid);
        channel.attr(ChannelAttr.CHANNEL).set(command.getChannel());
        channel.attr(ChannelAttr.DEVICE_ID).set(command.getDeviceId());
        channel.attr(ChannelAttr.LANGUAGE).set(command.getLanguage());

        sessionService.saveSession(command);
        sessionGroup.add(channel);

        /*
         *向客户端发送bind响应
         */
        channel.writeAndFlush(reply);

        /*
         * 发送上线事件到集群中的其他实例，控制其他设备下线
         */
        signalRedisTemplate.bind(JSON.toJSONString(command));
    }

    /**
     * 群聊上线
     *
     * @param channel
     * @param body
     * @param reply
     * @param uid
     */
    private void bindMember(Channel channel, SentBody body, ReplyBody reply, String uid) {
        String name = body.get("name");
        long roomId = Long.parseLong(body.get("roomId"));
        //User user = new User();
        //user.setUid(uid);
        //user.setName(name);
        //user.setRoomId(roomId);
        //userService.add(user);

        channel.attr(ChannelAttr.UID).set(uid);
        channel.attr(AttributeKey.valueOf("name")).set(name);
        channel.attr(ChannelAttr.TAG).set(String.valueOf(roomId));
        tagsessionGroup.add(channel);

        channel.writeAndFlush(reply);
    }

}
